#pragma once
#include <string>
#include <jsoncpp/json/json.h>

// 应用层协议完整的报头+报文格式
//"len\r\n{jsonStr}\r\n" —— "len"：报文的长度；"\r\n"：区分len和报文
// 使用"\r\n"作为分割原因是在Debug测试时打印出来的结果：一行是len、一行是报文的形式，也可以用其他作为分割
//"{jsonStr}\r\n"能不能只以"\r\n"作为分割呢？
// 不能因为报文中有可能也有\r\n，如果查找\r\n，取其前面的内容作为报文是不行的
static const std::string sep = "\r\n";
// 添加报头
std::string EnCode(const std::string &jsonStr)
{
    int len = jsonStr.size();
    std::string lenStr = std::to_string(len);
    return lenStr + sep + jsonStr + sep;
}
//"le"、"len\r"
//"len\r\n{js"
//"len\r\n{jsonStr}\r\nlen\r\n{js"
// 从传的流中提取出一个完整的报文，如果流中没有一个完整的报文返回空，如果有返回一个完整的报文字符串
std::string DeCode(std::string &packageStream)
{
    size_t n = packageStream.find(sep);
    if (n == std::string::npos)
        return "";
    std::string numStr = packageStream.substr(0, n);
    int len = std::stoi(numStr);
    // 当前这个完整报文的长度
    int total = numStr.size() + len + 2 * sep.size();
    if (packageStream.size() < total)
        return "";
    int pos = n + sep.size();
    std::string jsonStr = packageStream.substr(pos, len);
    // 提取到一个完整的jsonStr串，删掉packageStream中头部字段
    packageStream.erase(0, total);
    return jsonStr;
}

// 请求
class Request
{
public:
    Request(int x = 1, int y = 1, char oper = '+')
        : _x(x), _y(y), _oper(oper)
    {
    }
    // 序列化：将结构化字段转换成字符串
    void Serialize(std::string &out)
    {
        // 先定义一个中间值，Value类型的对象root
        Json::Value root;
        root["x"] = _x; // 一个键值对应一个value值，value可以是任意类型，包括对象
        root["y"] = _y;
        root["oper"] = _oper;
        // 再定义一个FastWriter类型的对象，使用其内部的write()方法将中间值root序列化成字符串
        Json::FastWriter writer;
        std::string s = writer.write(root);
        out = s;
    }
    // 反序列化：将字符串转换成结构化字段
    bool Deserialize(std::string &in)
    {
        Json::Value root;
        // 将序列化后的字符串，转化成Value的中间值
        Json::Reader reader;
        bool res = reader.parse(in, root);
        if (res)
        {
            _x = root["x"].asInt(); // 将root中的"x"对应的value值作为正数给给_x
            _y = root["y"].asInt();
            _oper = root["oper"].asInt();
            return true;
        }
        return false;
    }
    int RetX()
    {
        return _x;
    }
    int RetY()
    {
        return _y;
    }
    char RetOper()
    {
        return _oper;
    }
    ~Request()
    {
    }

    // private:
    int _x;
    int _y;
    char _oper;
};

// 回应
class Response
{
public:
    Response()
        : _result(2), _code(0), _describe("Calculation successful")
    {
    }
    // 序列化
    void Serialize(std::string &out)
    {
        // 先定义一个中间值，Value类型的对象root
        Json::Value root;
        root["result"] = _result; // 一个键值对应一个value值，value可以是任意类型，包括对象
        root["code"] = _code;
        root["describe"] = _describe;
        // 再定义一个FastWriter类型的对象，使用其内部的write()方法将中间值root序列化成字符串
        Json::FastWriter writer;
        std::string s = writer.write(root);
        out = s;
    }
    // 反序列化
    bool Deserialize(std::string &in)
    {
        Json::Value root;
        // 将序列化后的字符串，转化成Value的中间值
        Json::Reader reader;
        bool res = reader.parse(in, root);
        if (res)
        {
            _result = root["result"].asInt(); // 将root中的"x"对应的value值作为正数给给_x
            _code = root["code"].asInt();
            _describe = root["describe"].asString();
            return true;
        }
        return false;
    }
    ~Response()
    {
    }

    // private:
    int _result;
    int _code;             // 结果码0：计算成功 1：除0错误 2：其他非法操作
    std::string _describe; // 对结果码的描述
};